#pragma once
#include <string>
#include <memory> // std::auto_ptr
#include <cstdlib> // std::exit
#include <iostream>
#include <odb/database.hxx>
#include <odb/mysql/database.hxx>
#include "logger.hpp"
#include "message.hxx"
#include "message-odb.hxx"
#include "mysql.hpp"

namespace zrb
{
    //使用ODB框架对会话成员表的操作
    class MessageTable
    {
    public:
        using ptr = std::shared_ptr<MessageTable>;
        MessageTable(const std::shared_ptr<odb::core::database>& db)
            :_db(db)
        {}

    //新增消息
    bool insert(Message& msg)
    {
        try 
        {
            //3.获取事务对象开启事务
            odb::transaction trans(_db->begin());
            _db->persist(msg);
            //4.提交事务
            trans.commit();
        }
        catch (std::exception &e) 
        {
            LOG_ERROR("新增{}数据出错：{}",msg.message_id(),e.what());
            return false;
        }
        return true;
    }
    //删除消息
    bool remove(const std::string& ssid)
    {
        try 
        {
            //3.获取事务对象开启事务
            odb::transaction trans(_db->begin());
            typedef odb::query<Message> query;
            typedef odb::result<Message> result;
            _db->erase_query<Message>(query::session_id == ssid); //删除条件
            //4.提交事务
            trans.commit();
        }
        catch (std::exception &e) 
        {
            LOG_ERROR("删除会话所有数据出错：{}",e.what());
            return false;
        }
        return true;
    }
    //通过会话 ID，时间范围，获取指定时间段之内的消息，并按时间进行排序
    std::vector<Message> range(const std::string& ssid,boost::posix_time::ptime stime,boost::posix_time::ptime etime) //会话id 开始时间 结束时间
    {
        std::vector<Message> res;
        try {
            //获取事务对象开启事务
            odb::transaction trans(_db->begin());
            typedef odb::query<Message> query;
            typedef odb::result<Message> result;

            //查询
            result r(_db->query<Message>(query::session_id == ssid &&
                query::create_time >= stime &&
                query::create_time <= etime));

            //遍历
            for (auto it = r.begin(); it != r.end(); ++it) 
            {
                res.push_back(*it);
            }
            //5. 提交事务
            trans.commit();
        }
        catch (std::exception &e) 
        {
            LOG_ERROR("查询区间消息出错：{}-{}-{}-{}",ssid,
            boost::posix_time::to_simple_string(stime),
            boost::posix_time::to_simple_string(etime),
            e.what());
        }
        std::reverse(res.begin(),res.end()); //按照时间正向排序
        return res;
    }
    //通过会话 ID，消息数量，获取最近的 N 条消息（逆序+limit 即可）
    std::vector<Message> recent(const std::string& ssid,int count)
    {
        std::vector<Message> res;
        try {
            //获取事务对象开启事务
            odb::transaction trans(_db->begin());
            typedef odb::query<Message> query;
            typedef odb::result<Message> result;

            //条件
            //查询会话ID是ssid,并且按照时间降序,限制在count条消息
            std::stringstream cond;
            cond << "session_id='" << ssid << "' ";
            cond << "order by create_time desc ";
            cond << "limit " << count;

            //查询
            result r(_db->query<Message>(cond.str()));

            //遍历
            for (auto it = r.begin(); it != r.end(); ++it) 
            {
                res.push_back(*it);
            }
            //5. 提交事务
            trans.commit();
        }
        catch (std::exception &e) 
        {
            LOG_ERROR("查询某个会话的消息出错：{}",e.what());
        }
        std::reverse(res.begin(),res.end()); //按照时间正向排序
        return res;
    }

    ~MessageTable()
    {}

    private:
        std::shared_ptr<odb::core::database> _db; 
    };
}